from ..data_structures.base_structures import AttributeType, Vegetation, Building
from .map_converter import map_to_shp


def crypticity(map, shp_path=None, config=None):
    """
        输入 Map 对象，输出一个新的 Map，其中只包含符合隐蔽条件的六角格网。
        如果指定 shp_path，则导出为 shapefile。

        :param map: 输入的 Map 对象
        :param shp_path: 输出 shapefile 路径（可选）
        :param config: 用户自定义参数字典，例如：
            {
                "FOREST": {"canopy": 0.7, "H": 4.0},
                "SHRUBWOOD": {"D": 0.25, "H": 2.5},
                "PLOWLAND": {"D": 0.2, "H": 2.0}
            }
        """
    # 默认参数
    default_config = {
        "FOREST": {"canopy": 0.6, "H": 3.0},
        "SHRUBWOOD": {"D": 0.2, "H": 2.0},
        "PLOWLAND": {"D": 0.15, "H": 1.5}
    }

    # 用户配置覆盖默认参数
    if config is not None:
        for k, v in config.items():
            if k in default_config:
                default_config[k].update(v)

    # 用原始 map 的类动态创建一个新 map（保持一致性）
    new_map = map.__class__()

    for index, cell in map.cells.items():
        concealed = False

        # --- Vegetation checks ---
        veg_attr = cell.get_attribute(Vegetation)
        if veg_attr is not None:
            veg_type = veg_attr.get_sub_attribute(Vegetation.Type)
            canopy = veg_attr.get_sub_attribute(Vegetation.CanopyClosure)
            H = veg_attr.get_sub_attribute(Vegetation.AverageHeight)
            D = veg_attr.get_sub_attribute(Vegetation.Density)

            veg_type = veg_type.get_value() if veg_type else None
            canopy = float(canopy.get_value()) if canopy else None
            H = float(H.get_value()) if H else None
            D = float(D.get_value()) if D else None

            if veg_type == AttributeType.FOREST.value:
                thresholds = default_config["FOREST"]
                if canopy is not None and H is not None and canopy >= thresholds["canopy"] and H >= thresholds["H"]:
                    concealed = True

            elif veg_type == AttributeType.SHRUBWOOD.value:
                thresholds = default_config["SHRUBWOOD"]
                if D is not None and H is not None and D >= thresholds["D"] and H >= thresholds["H"]:
                    concealed = True

            elif veg_type == AttributeType.PLOWLAND.value:
                thresholds = default_config["PLOWLAND"]
                if D is not None and H is not None and D >= thresholds["D"] and H >= thresholds["H"]:
                    concealed = True

        # --- Building rule ---
        bld_attr = cell.get_attribute(Building)
        if bld_attr is not None:
            bld_count = 0
            for n_hid in cell.neighbors:
                n_cell = map.cells.get(n_hid, None)
                if n_cell and n_cell.get_attribute(Building) is not None:
                    bld_count += 1
            if bld_count >= 3:
                concealed = True

        # 如果满足隐蔽条件，把 cell 拷贝到 new_map
        if concealed:
            new_cell = cell.__class__(index)  # 保持 cell 类型一致
            new_cell.attributes = cell.attributes.copy()
            new_cell.neighbors = cell.neighbors.copy()
            new_map.cells[index] = new_cell

    # === 导出为 Shapefile ===
    if shp_path:
        map_to_shp(new_map, shp_path)

    return new_map, shp_path


